package com.mercury.base.util;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Optional;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * @author mercury
 * @date 2021/2/1 11:00 上午
 */
@Slf4j
public class UnzipUtils {
    /**
     * 先base64解密，再解压
     *
     * @param resource 源数据
     * @return java.lang.String
     * @author mercury
     * @date 2021/02/01 11:04
     */
    public static String base64DecodeAndUnGzip(String resource) {
        return Optional.ofNullable(resource).map(x -> {
            try {
                return new String(unGzip(Base64Util.decode(x)));
            } catch (Exception e) {
                log.error("base64 decode and unGzip fail ,error:", e);
                return null;
            }
        }).orElse(null);
    }

    /**
     * zip后base64编码
     *
     * @param resource 资源
     * @return java.lang.String
     * @author mercury
     * @date 2021/02/01 11:04
     */
    public static String base64EncodeAndGzip(String resource) {
        try {
            return Base64Util.encode(gzip(JSON.toJSONBytes(resource)));
        } catch (Exception e) {
            log.error("base64 encode and gzip fail ,error:", e);
            return null;
        }
    }


    public static byte[] gzipStr(String data) throws Exception {
        return gzip(data.getBytes(StandardCharsets.UTF_8));
    }

    public static String unGzipStr(byte[] data) throws Exception {
        return new String(unGzip(data), StandardCharsets.UTF_8);
    }

    public static byte[] gzip(byte[] data) throws Exception {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(bos);
        gzip.write(data);
        gzip.finish();
        gzip.close();
        byte[] ret = bos.toByteArray();
        bos.close();
        return ret;
    }

    public static byte[] unGzip(byte[] data) throws Exception {
        ByteArrayInputStream bis = new ByteArrayInputStream(data);
        GZIPInputStream gzip = new GZIPInputStream(bis);
        byte[] buf = new byte[1024];
        int num = -1;
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        while ((num = gzip.read(buf, 0, buf.length)) != -1) {
            bos.write(buf, 0, num);
        }
        gzip.close();
        bis.close();
        byte[] ret = bos.toByteArray();
        bos.flush();
        bos.close();
        return ret;
    }
}
